"""
AI分析服务模块 - 完整版
"""
import requests
import json
import time
import random
from typing import Dict, Any, Optional, Generator
from config import Config
from .prompt_generator import PromptGenerator


class AIService:
    """AI分析服务类"""

    @staticmethod
    def call_ai_api(prompt: str, max_retries: int = None) -> str:
        """
        调用OpenAI兼容的AI接口

        Args:
            prompt: 提示词
            max_retries: 最大重试次数

        Returns:
            AI响应内容
        """
        max_retries = max_retries or Config.AI_MAX_RETRIES

        if not Config.AI_API_KEY:
            class APIKeyError(Exception):
                def __init__(self, message, error_code):
                    super().__init__(message)
                    self.error_code = error_code

            raise APIKeyError("AI_API_KEY 未配置，请检查环境变量", "API_KEY_MISSING")

        headers = {
            'Authorization': f'Bearer {Config.AI_API_KEY}',
            'Content-Type': 'application/json',
        }

        data = {
            'model': Config.AI_MODEL,
            'messages': [
                {
                    'role': 'system',
                    'content': '你是一位专业的股票投资分析师，具有丰富的财务分析经验和市场洞察力。请基于提供的数据进行客观、专业的分析。'
                },
                {
                    'role': 'user',
                    'content': prompt
                }
            ],
            'temperature': 0.7,
            'max_tokens': 2000,
        }

        for attempt in range(max_retries):
            try:
                response = requests.post(
                    f'{Config.AI_API_BASE_URL}/chat/completions',
                    headers=headers,
                    json=data,
                    timeout=Config.AI_TIMEOUT
                )

                if response.status_code == 200:
                    result = response.json()
                    return result['choices'][0]['message']['content']
                elif response.status_code == 429:
                    if attempt < max_retries - 1:
                        sleep_time = (2 ** attempt) + random.uniform(0, 1)
                        print(f"AI API限流，{sleep_time:.1f}秒后重试 (尝试 {attempt + 1}/{max_retries})")
                        time.sleep(sleep_time)
                        continue
                    else:
                        raise Exception(f"AI API rate limit exceeded after {max_retries} retries")
                else:
                    error_info = response.json() if response.headers.get('content-type', '').startswith('application/json') else response.text
                    raise Exception(f"AI API调用失败 ({response.status_code}): {error_info}")

            except requests.exceptions.RequestException as e:
                if attempt < max_retries - 1:
                    print(f"AI API请求错误，重试中: {str(e)}")
                    time.sleep(1)
                    continue
                else:
                    raise Exception(f"AI API请求失败: {str(e)}")

        raise Exception("AI API调用失败：未知错误")

    @staticmethod
    def stream_ai_response(messages: list) -> Generator[str, None, None]:
        """
        流式调用AI API

        Args:
            messages: 对话消息列表

        Yields:
            流式响应内容
        """
        if not Config.AI_API_KEY:
            yield json.dumps({'error': 'AI_API_KEY 未配置'})
            return

        headers = {
            'Authorization': f'Bearer {Config.AI_API_KEY}',
            'Content-Type': 'application/json',
        }

        data = {
            'model': Config.AI_MODEL,
            'messages': messages,
            'temperature': 0.7,
            'max_tokens': 2000,
            'stream': True
        }

        try:
            response = requests.post(
                f'{Config.AI_API_BASE_URL}/chat/completions',
                headers=headers,
                json=data,
                stream=True,
                timeout=Config.AI_TIMEOUT
            )

            if response.status_code == 200:
                for line in response.iter_lines():
                    if line:
                        line_str = line.decode('utf-8')
                        if line_str.startswith('data: '):
                            data_str = line_str[6:]
                            if data_str == '[DONE]':
                                break
                            try:
                                data_json = json.loads(data_str)
                                if 'choices' in data_json and len(data_json['choices']) > 0:
                                    delta = data_json['choices'][0].get('delta', {})
                                    if 'content' in delta:
                                        content = delta['content']
                                        yield json.dumps({'content': content})
                            except json.JSONDecodeError:
                                continue
            else:
                error_msg = f"AI API error: {response.status_code}"
                yield json.dumps({'error': error_msg})

        except Exception as e:
            error_msg = str(e)
            yield json.dumps({'error': f'Streaming error: {error_msg}'})

    @staticmethod
    def build_specialized_analysis_prompt(data: Dict[str, Any]) -> str:
        """
        根据分析类型构建专门化的AI分析提示词 - 使用提示词生成器

        Args:
            data: 包含分析类型和用户问题的数据字典

        Returns:
            专门化的提示词
        """
        analysis_type = data.get('analysis_type', 'comprehensive')

        # 使用提示词生成器生成对应类型的提示词
        return PromptGenerator.generate_prompt_by_type(data, analysis_type)